package com.cy.job;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cy.model.domain.User;
import com.cy.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
@ResponseBody
@RequestMapping("/preCache")
@Slf4j
public class PreCacheJob {

    @Resource
    private UserService userService;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private RedissonClient redissonClient;


    // 预热缓存
    @GetMapping("/doCacheRecover")
    public void doCacheRecover() {
        // 1.获取分布式锁
        RLock lock = redissonClient.getLock("yupao:precachejob:docacherecover:lock");
        // 2. 从数据库查询热门用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        Page<User> userPage = userService.page(new Page<>(1, 10), queryWrapper);
        List<User> userList = userPage.getRecords();
        // 3. 尝试获取锁
        try {
            boolean isLock = lock.tryLock();
            // 4. 判断获取锁是否成功
            if (!isLock) {
                log.error("获取锁失败");
            }
            // 5. 获取锁成功，查询数据库到缓存
            //给每个user都查询对应的缓存
           userList.forEach(e -> {
               Page<User> page = userService.page(new Page<>(1, 20), queryWrapper);
               String key = String.format("yupao:user:recommend:%s", e.getId());
               ValueOperations valueOperations = redisTemplate.opsForValue();
               //写入缓存
               try {
                   valueOperations.set(key,page,300000, TimeUnit.MILLISECONDS);
               } catch (Exception ex) {
                   log.error("redis set key error", ex);
                   ex.printStackTrace();
               }
           });
        } catch (Exception e) {
            log.error("预热数据失败");
        }finally {
            // 只能释放自己的锁
            if (lock.isHeldByCurrentThread()) {
                System.out.println("unLock: " + Thread.currentThread().getId());
                lock.unlock();
            }
        }
    }
}